package com.echo.code.thread.mode.nio2;

import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

import com.echo.code.thread.mode.listener.EventBus;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Objects;

/**
 * DirectoryTargetMonitor Created by baiyap on 2018/9/24.
 */
public class DirectoryTargetMonitor {

  private EventBus bus;
  private Path path;
  private WatchService service;
  private volatile boolean start;

  public DirectoryTargetMonitor(EventBus bus, String targetPath) throws IOException {
    this.bus = bus;
    this.path = Paths.get(targetPath);
    this.service = FileSystems.getDefault().newWatchService();
    this.start = false;
  }

  public void startMonitor(String topic) throws IOException {
    // 为路径注册感兴趣的事件
    path.register(service, ENTRY_MODIFY, ENTRY_DELETE, ENTRY_CREATE);
    start = true;
    while (start) {
      WatchKey watchKey = null;
      try {
        // 当有事件发生时会返回对应的WatchKey
        watchKey = service.take();
        watchKey.pollEvents().forEach(event -> {
          // 提交FileChangeEvent到EventBus
          bus.post(new FileChangeEvent(path.resolve((Path) event.context()), event.kind()), topic);
        });
      } catch (InterruptedException e) {
        service.close();
        start = false;
        bus.close();
      } finally {
        if (Objects.nonNull(watchKey)) {
          watchKey.reset();
        }
      }
    }
  }
}

